using System;
using GeoFramework;
using GeoFramework.IO;
using GeoFramework.Gps;

namespace GeoFramework.Gps.Emulators
{
	/// <summary>
	/// Represents a virtual GPS device.
	/// </summary>
	/// <remarks><para>This class allows GPS device emulators to be found during Automatic GPS Device Detection.
	/// This class is typically used for testing situations where an application must be tested against
	/// several unique kinds of GPS devices.  By using virtual GPS devices, an application can test behaviors
	/// without requiring testers to manually switch GPS device hardware.</para>
	/// <para>To use this class, create a new instance and specify the emulator which will provide raw GPS
	/// data.  Any class can be used so long as it inherits from the Emulator class.  Next, instruct GPS.NET to
	/// include this device during automatic device detection by calling the RegisterGpsDevice method of the
	/// Devices class.</para>
	/// <example>
	/// This example registers a virtual DeLorme Earthmate(tm) GPS device with GPS.NET.  Once registered, GPS.NET
	/// will include the device during automatic GPS device detection.
	/// <code lang="cs">
	/// // Create a new DeLorme Earthmate Emulator
	/// DeLormeEarthmateUsbEmulator Emulator = new DeLormeEarthmateUsbEmulator();
	/// // Create a virtual GPS device using this emulator
	/// VirtualDevice VirtualGpsDevice = new VirtualDevice(Emulator);
	/// // Register the device so that it is picked up during automatic device detection
	/// GeoFramework.IO.Devices.RegisterGpsDevice(VirtualGpsDevice);
	/// </code>
	/// <code lang="vb">
	/// ' Create a new DeLorme Earthmate Emulator
	/// Dim Emulator As New DeLormeEarthmateUsbEmulator()
	/// ' Create a virtual GPS device using this emulator
	/// Dim VirtualGpsDevice As New VirtualDevice(Emulator)
	/// ' Register the device so that it is picked up during automatic device detection
	/// GeoFramework.IO.Devices.RegisterGpsDevice(VirtualGpsDevice)
	/// </code>
	/// </example>
	///  </remarks>
    public sealed class VirtualDevice : Device
	{
		private Emulator pEmulator;

		public VirtualDevice(Emulator emulator)
		{
			if(emulator == null)
				throw new ArgumentNullException("emulator", "A virtual device can only be created when specifying a non-null emulator.");
			pEmulator = emulator;
			SetProtocol(emulator.Protocol);
		}

		public override System.IO.Stream GetHardwareStream()
		{
			// Return a new emulator instance
			return pEmulator.Clone();
		}

		public override string ToString(string format, IFormatProvider formatProvider)
		{
			return pEmulator.ToString (format, formatProvider);
		}

		public string DeviceName
		{
			get
			{
				return pEmulator.Name;
			}
		}

        public Emulator Emulator
        {
            get
            {
                return pEmulator;
            }
        }
	}
}
